package net.ib.mtalk.account;

import net.ib.mtalk.R;
import net.ib.mtalk.constant.MTalkConstant;
import net.ib.mtalk.global.GlobalPreferences;
import net.ib.mtalk.util.GpbSupport;
import net.ib.mtalk.util.MTalkLogWriter;
import android.accounts.AbstractAccountAuthenticator;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.accounts.NetworkErrorException;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class MTalkAccountService extends Service{
	
	private static AccountAuthenticator mAccountAuthenticator = null;
	
	@Override
	public void onCreate() {
		MTalkLogWriter.v("onCreate : " + getClass().getName());
	}
		
	@Override
	public IBinder onBind(Intent intent) {
		IBinder ret = null;
		if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
			ret = getAuthenticator().getIBinder();
		}
		return ret;
	}
	
	private AccountAuthenticator getAuthenticator() {
		if (mAccountAuthenticator == null) {
			mAccountAuthenticator = new AccountAuthenticator(getApplicationContext());
		}
		return mAccountAuthenticator;
	}
	
	private static class AccountAuthenticator extends AbstractAccountAuthenticator {

		private Context mContext;
		
		public AccountAuthenticator(Context context) {
			super(context);
			mContext = context;
		}

		@Override
		public Bundle editProperties(AccountAuthenticatorResponse response,
				String accountType) {
			MTalkLogWriter.v("Edit Account Properties : " + getClass().getName());
			return null;
		}

		@Override
		public Bundle addAccount(AccountAuthenticatorResponse response,
				String accountType, String authTokenType,
				String[] requiredFeatures, Bundle options)
				throws NetworkErrorException {
			
			MTalkLogWriter.v("Add Account : " + getClass().getName());
					
			final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
			intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
			intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
			
			final Bundle result = new Bundle();
			result.putParcelable(AccountManager.KEY_INTENT, intent);
			
			return result;
		}

		@Override
		public Bundle confirmCredentials(AccountAuthenticatorResponse response,
				Account account, Bundle options) throws NetworkErrorException {
			MTalkLogWriter.v("Confirm Credentials : " + getClass().getName());
			return null;
		}

		@Override
		public Bundle getAuthToken(AccountAuthenticatorResponse response,
				Account account, String authTokenType, Bundle options)
				throws NetworkErrorException {
			MTalkLogWriter.v("get Auth Token : " + getClass().getName());
			if (!authTokenType.equals(MTalkConstant.ACCOUNT_TYPE)) {
				final Bundle result = new Bundle();
				result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");
				return result;
			}
			final AccountManager am = AccountManager.get(mContext);
			final String password = am.getPassword(account);
			
			if (password != null) {
				if (GpbSupport.UuidMsgToString(GlobalPreferences.getUserUUID()).equals(password)) {
					final Bundle result = new Bundle();
					result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
					result.putString(AccountManager.KEY_ACCOUNT_TYPE, MTalkConstant.ACCOUNT_TYPE);
					result.putString(AccountManager.KEY_AUTHTOKEN, password);
					return result;
				}
			}
			
			final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
			intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
			intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
			intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
			
			final Bundle bundle = new Bundle();
			bundle.putParcelable(AccountManager.KEY_INTENT, intent);
			return bundle;
		}

		@Override
		public String getAuthTokenLabel(String authTokenType) {
			MTalkLogWriter.v("get Auth Token label : " + getClass().getName());
			if (authTokenType.equals(MTalkConstant.ACCOUNT_TYPE)) {
				return mContext.getString(R.string.buddy_talk_tag);
			}
			return null;
		}

		@Override
		public Bundle updateCredentials(AccountAuthenticatorResponse response,
				Account account, String authTokenType, Bundle options)
				throws NetworkErrorException {
			MTalkLogWriter.v("update Credentials : " + getClass().getName());
			final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
			intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
			intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
			intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, false);
			
			final Bundle bundle = new Bundle();
			bundle.putParcelable(AccountManager.KEY_INTENT, intent);
			return bundle;
		}

		@Override
		public Bundle hasFeatures(AccountAuthenticatorResponse response,
				Account account, String[] features)
				throws NetworkErrorException {
			MTalkLogWriter.v("has features : " + getClass().getName());
			final Bundle result = new Bundle();
			result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
			return result;
		}
		
	}

}
